package com.ccp.dev.system.controller;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.consts.UrlConstants;
import com.ccp.dev.core.basic.internationalization.SysBaseController;
import com.ccp.dev.core.basic.model.SysAuditModelType;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.scheduler.TriggerObject;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.RequestUtil;
import com.ccp.dev.core.util.log.SysAuditThreadLocalHolder;
import com.ccp.dev.system.service.SchedulerService;
import org.apache.commons.text.StringEscapeUtils;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;

/**
 * 定时计划controller
 * @author nd
 */
@Controller
@Action(ownermodel = SysAuditModelType.SYSTEM_SETTING)
@RequestMapping(UrlConstants.PROJECT_ROOT+UrlConstants.PROJECT_MODULE_SYSTEM+"/scheduler")
public class SchedulerController extends SysBaseController {

    @Autowired
    private SchedulerService schedulerService;

    /**
     * 查询定时任务list
     * @param request 请求
     * @return ResultData
     */
    @GetMapping("/jobList")
    @ResponseBody
    @Action(description = "查询定时任务list列表",
            detail = "查询定时任务list列表<#if success>成功<#else>失败</#if>",
            exectype = "查询日志")
    public ResultData queryJobList(HttpServletRequest request){
        try{
            QueryFilter queryFilter = new QueryFilter(request);
            List<JobDetail> list = schedulerService.queryJobList(queryFilter);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("operation.success",queryFilter.getPageBean().getTotalCount(),list);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataSuccess("operation.failure");
        }
    }

    /**
     * 保存任务 新增|修改 任务
     * @param request 请求
     * @return ResultData
     */
    @PostMapping("/addJob")
    @ResponseBody
    @Action(description="添加定时任务",
            detail="添加定时任务【${jobName}】<#if success>成功<#else>失败</#if>"
            , exectype = "编辑日志"
    )
    public ResultData saveJob(HttpServletRequest request){
        String jobName = RequestUtil.getString(request,"jobName");
        String className = RequestUtil.getString(request,"className");
        String parameterJson = RequestUtil.getString(request,"parameterJson");
        parameterJson = StringEscapeUtils.unescapeHtml4(parameterJson);
        String memo = RequestUtil.getString(request,"memo");
        SysAuditThreadLocalHolder.putParamerter("jobName", jobName);
        try {
            schedulerService.saveJob(jobName,className,parameterJson,memo);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("save.success");
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("save.failure");
        }
    }

    /**
     * 删除任务
     * @return ResultData
     */
    @GetMapping("/delJob")
    @ResponseBody
    @Action(description="删除定时任务",
            detail= "删除定时任务【${jobName}】<#if success>成功<#else>失败</#if>" ,
            exectype = "删除日志"
    )
    public ResultData delJob(HttpServletRequest request){
        String jobName = RequestUtil.getString(request,"jobName");
        SysAuditThreadLocalHolder.putParamerter("jobName", jobName);
        try {
            schedulerService.delJob(jobName);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("delete.success");
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataSuccess("delete.failure");
        }
    }
    /**
     *验证类
     * @param request 请求
     */
    @RequestMapping("/validClass")
    @ResponseBody
    @Action(description="验证类是否存在",
            detail= "验证【${className}】类是否存在" ,
            exectype = "查询日志"
    )
    public ResultData validClass(HttpServletRequest request) {
        String className = RequestUtil.getString(request, "className");
        SysAuditThreadLocalHolder.putParamerter("className", className);
        boolean rtn = BeanUtils.validClass(className);
        if (rtn) {
            return getResultDataSuccess("quartz.verification.class.exists");
        }
        return getResultDataError("quartz.verification.class.not.exists");
    }

    /**
     * 执行任务
     * @param request 请求
     * @return ResultData
     */
    @GetMapping("/executeJob")
    @ResponseBody
    @Action(description="执行定时任务",
            detail= "执行【${jobName}】任务<#if success>成功<#else>失败</#if>" ,
            exectype = "编辑日志"
    )
    public ResultData executeJob(HttpServletRequest request){
        String jobName=RequestUtil.getString(request,"jobName");
        SysAuditThreadLocalHolder.putParamerter("jobName", jobName);
        try {
            schedulerService.executeJob(jobName);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("quartz.run.success");
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("quartz.run.failure");
        }
    }
    /**
     * 保存定时计划
     * @param request 请求
     * @return ResultData
     */
    @PostMapping("/addTrigger")
    @ResponseBody
    @Action(
            description="添加定时计划",
            detail="添加定时计划【${jobName}】<#if success>成功<#else>失败</#if>",
            exectype = "编辑日志"
    )
    public ResultData saveTrigger(HttpServletRequest request){
        String trigName=RequestUtil.getString(request, "name");
        String jobName=RequestUtil.getString(request,"jobName");
        String planJson=RequestUtil.getString(request,"planJson");
        SysAuditThreadLocalHolder.putParamerter("jobName", jobName);
        try {
            //判断触发器是否存在
            boolean rtn=schedulerService.isTriggerExists(trigName);
            if(rtn){
                SysAuditThreadLocalHolder.putParamerter("success", false);
                return getResultDataError("quartz.verification.trigger.exists");
            }
            schedulerService.saveTrigger(jobName,trigName,planJson);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("save.success");
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("save.failure");
        } catch (ParseException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("save.failure");
        }
    }

    /**
     * 查询job的计划列表
     * @param request 请求
     * @return ResultData
     */
    @Action(
            description="查询job的计划列表",
            detail="查询【${jobName}】的计划列表<#if success>成功<#else>失败</#if>",
            exectype = "查询日志"
    )
    @GetMapping("/triggerList")
    @ResponseBody
    public ResultData queryTriggerList(HttpServletRequest request,Model model){
        String jobName = RequestUtil.getString(request,"jobName");
        SysAuditThreadLocalHolder.putParamerter("jobName", jobName);
        List<Trigger> listTrigger= null;
        List<TriggerObject> list= null;
        HashMap<String, Trigger.TriggerState> mapState = null;
        try {
            listTrigger = schedulerService.queryTriggerListByJobName(jobName);
            mapState=schedulerService.getTriggerStatus(listTrigger);
            list = schedulerService.queryTriggerListByJobName(jobName,mapState);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("operation.success",0,list);
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("operation.failure");
        }
    }
    /**
     * 删除任务定时计划
     * @param request
     */
    @GetMapping("/delTrigger")
    @ResponseBody
    @Action(
            description="删除定时计划计划" ,
            detail="删除定时计划作业计划【${triggerName}】<#if success>成功<#else>失败</#if>",
            exectype = "删除日志"
    )
    public ResultData delTrigger(HttpServletRequest request){
        String triggerName = RequestUtil.getString(request,"triggerName");
        SysAuditThreadLocalHolder.putParamerter("triggerName", triggerName);
        try {
            schedulerService.delTrigger(triggerName);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("delete.success");
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("delete.failure");
        }
    }

    /**
     * 启用或禁用定时任务计划
     * @param request 请求
     * @return ResultData
     */
    @GetMapping("/toggleTriggerRun")
    @ResponseBody
    @Action(
            description="启用或禁用定时计划" ,
            detail="设置定时计划作业【${triggerName}】的计划状态：<#if success>成功<#else>失败</#if>",
            exectype = "编辑日志"
    )
    public ResultData toggleTriggerRun(HttpServletRequest request){
        String triggerName=RequestUtil.getString(request, "triggerName");
        SysAuditThreadLocalHolder.putParamerter("triggerName", triggerName);
        try {
            schedulerService.toggleTriggerRun(triggerName);
            SysAuditThreadLocalHolder.putParamerter("success", true);
             return getResultDataSuccess("toggle.success");
        } catch (SchedulerException e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("toggle.failure");
        }
    }
    /**
     * 修改定时器的状态
     * @param request 请求
     * @throws Exception 异常
     */
    @Action(
            description="修改定时器的状态" ,
            detail="修改定时器的状态<#if success>成功<#else>失败</#if>",
            exectype = "编辑日志"
    )
    @RequestMapping("changeStart")
    @ResponseBody
    public ResultData changeStart(HttpServletRequest request){
        String resultMsg;
        boolean isStandby = RequestUtil.getBoolean(request, "isStandby");
        try {
            //如果是挂起状态就启动，否则就挂起
            if (isStandby) {
                schedulerService.start();
                resultMsg="quartz.start.success";
            }else {
                schedulerService.shutdown();
                resultMsg="quartz.stop.success";
            }
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess(resultMsg);
        } catch (Exception e) {
            if (isStandby) {
                resultMsg="quartz.start.failure";
            }else {
                resultMsg="quartz.stop.failure";
            }
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError(resultMsg);
        }
    }
    /**
     * 跳转到定时计划列表页
     * @return html文件前缀
     */
    @Action( description="定时任务列表页页面跳转" , exectype = "页面跳转日志" )
    @GetMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/jobList")
    public String viewJobList(HttpServletRequest request,Model model){
        QueryFilter queryFilter = new QueryFilter(request);
        List<JobDetail> list= null;
        try {
            boolean isInStandbyMode = schedulerService.isInStandbyMode();
            list = schedulerService.queryJobList(queryFilter);
            model.addAttribute("isStandby",isInStandbyMode);

        } catch (SchedulerException e) {
            //TODO catcht没有处理
            e.printStackTrace();
        }
        model.addAttribute("jobList",list);
        return "scheduler/jobList";
    }
    /**
     * 跳转到添加定时任务页
     * @return html文件前缀
     */
    @Action( description="添加定时任务页页面跳转" , exectype = "页面跳转日志" )
    @GetMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/addJob")
    public String viewJobAdd(){
        return "scheduler/jobAdd";
    }

    /**
     * 跳转到定时计划列表页
     * @return html文件前缀
     */
    @Action( description="定时计划列表页页面跳转" , exectype = "页面跳转日志" )
    @GetMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/triggerList")
    public String viewTriggerList(HttpServletRequest request,Model model){
        String jobName = RequestUtil.getString(request,"jobName");
        model.addAttribute("jobName",jobName);
        return "scheduler/triggerList";
    }

    /**
     * 跳转到添加定时计划页
     * @return html文件前缀
     */
    @Action( description="添加定时计划页页面跳转" , exectype = "页面跳转日志" )
    @GetMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/addTrigger")
    public String viewTriggerAdd(HttpServletRequest request,Model model){
        String jobName = RequestUtil.getString(request,"jobName");
        model.addAttribute("jobName",jobName);
        return "scheduler/triggerAdd";
    }

}
